import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import java.util.ArrayList;

/**
 * A JPanel for creating profiles.
 *
 * @author Jacel Evasco
 * @author Rafael Carino
 * @author Christian Paul Rosquita
 * @author Roselle Nympha Lim
 * @version 1.0
 */
public class ProfileMaker extends JPanel {

    private JPanel labels = new JPanel();
    private JPanel fields = new JPanel();
    private JPanel buttons = new JPanel();
    private JPanel labelsAndFields = new JPanel();
    private JTextField iD = new JTextField();
    private JPasswordField pin = new JPasswordField();
    private JPasswordField confirmPin = new JPasswordField();
    private JButton okay = new JButton("okay");
    private JButton clear = new JButton("clear");
    private JLabel[] fieldLabels = {
        new JLabel("ID number", SwingConstants.RIGHT),
        new JLabel("PIN", SwingConstants.RIGHT),
        new JLabel("Confirm PIN", SwingConstants.RIGHT) };

    Connection connection = null;
    ResultSet resultSet = null;
    PreparedStatement preparedStatement = null;

    public ProfileMaker() {
        assemble();
        configure();
        design();
        setTriggers();
    }// end of ProfileMaker()

    private void prepareConnection() {
        try {
            connection = DatabaseUtility.prepareConnection();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, e);
        }
    } // end of prepareConnection method

    private void assemble() {
        // labels
        labels.setLayout(new BoxLayout(labels, BoxLayout.Y_AXIS));
        labels.add(fieldLabels[0]);
        labels.add(Box.createRigidArea(new Dimension(0, 15)));
        labels.add(fieldLabels[1]);
        labels.add(Box.createRigidArea(new Dimension(0, 15)));
        labels.add(fieldLabels[2]);
        // fields
        fields.setLayout(new BoxLayout(fields, BoxLayout.Y_AXIS));
        fields.add(iD);
        fields.add(Box.createRigidArea(new Dimension(0, 15)));
        fields.add(pin);
        fields.add(Box.createRigidArea(new Dimension(0, 15)));
        fields.add(confirmPin);
        // fields and labels
        labelsAndFields.setLayout(new BoxLayout(labelsAndFields,
            BoxLayout.X_AXIS));
        labelsAndFields
            .add(Box.createRigidArea(new Dimension(33, 0)));
        labelsAndFields.add(labels);
        labelsAndFields
            .add(Box.createRigidArea(new Dimension(30, 0)));
        labelsAndFields.add(fields);
        // buttons
        buttons.setLayout(new BoxLayout(buttons, BoxLayout.X_AXIS));
        buttons.add(Box.createRigidArea(new Dimension(173, 0)));
        buttons.add(clear);
        buttons.add(Box.createRigidArea(new Dimension(16, 0)));
        buttons.add(okay);
        // this
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        this.add(Box.createRigidArea(new Dimension(0, 45)));
        this.add(labelsAndFields);
        this.add(Box.createRigidArea(new Dimension(0, 25)));
        this.add(buttons);
    }// end of assemble()

    private void configure() {

    }// end of configure()

    private void design() {
        // sizes
        okay.setPreferredSize(new Dimension(100, 28));
        okay.setMinimumSize(new Dimension(100, 28));
        okay.setMaximumSize(new Dimension(100, 28));
        clear.setPreferredSize(new Dimension(100, 28));
        clear.setMinimumSize(new Dimension(100, 28));
        clear.setMaximumSize(new Dimension(100, 28));
        fieldLabels[0].setPreferredSize(new Dimension(110, 28));
        fieldLabels[0].setMinimumSize(new Dimension(110, 28));
        fieldLabels[0].setMaximumSize(new Dimension(110, 28));
        fieldLabels[1].setPreferredSize(new Dimension(110, 28));
        fieldLabels[1].setMinimumSize(new Dimension(110, 28));
        fieldLabels[1].setMaximumSize(new Dimension(110, 28));
        fieldLabels[2].setPreferredSize(new Dimension(110, 28));
        fieldLabels[2].setMinimumSize(new Dimension(110, 28));
        fieldLabels[2].setMaximumSize(new Dimension(110, 28));
        iD.setPreferredSize(new Dimension(287, 28));
        iD.setMinimumSize(new Dimension(287, 28));
        iD.setMaximumSize(new Dimension(287, 28));
        pin.setPreferredSize(new Dimension(287, 28));
        pin.setMinimumSize(new Dimension(287, 28));
        pin.setMaximumSize(new Dimension(287, 28));
        confirmPin.setPreferredSize(new Dimension(287, 28));
        confirmPin.setMinimumSize(new Dimension(287, 28));
        confirmPin.setMaximumSize(new Dimension(287, 28));
        labelsAndFields.setPreferredSize(new Dimension(500, 116));
        labelsAndFields.setMinimumSize(new Dimension(500, 116));
        labelsAndFields.setMaximumSize(new Dimension(500, 116));
        buttons.setPreferredSize(new Dimension(500, 28));
        buttons.setMinimumSize(new Dimension(500, 28));
        buttons.setMaximumSize(new Dimension(500, 28));
        this.setPreferredSize(new Dimension(500, 284));
        this.setMinimumSize(new Dimension(500, 284));
        this.setMaximumSize(new Dimension(500, 284));
        // font styles
        Font font = new Font("Segoe UI Light", Font.PLAIN, 16);
        Font labelFont = new Font("Segoe UI", Font.BOLD, 14);
        Font buttonFont = new Font("Segoe UI", Font.BOLD, 14);
        iD.setFont(font);
        pin.setFont(font);
        confirmPin.setFont(font);
        okay.setFont(buttonFont);
        clear.setFont(buttonFont);
        fieldLabels[0].setFont(labelFont);
        fieldLabels[1].setFont(labelFont);
        fieldLabels[2].setFont(labelFont);
        // borders
        iD.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
        pin.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
        confirmPin.setBorder(BorderFactory.createLineBorder(
            Color.BLACK, 1));
        // backgrounds
        labels.setOpaque(false);
        fields.setOpaque(false);
        buttons.setOpaque(false);
        labelsAndFields.setOpaque(false);
        // buttons
        okay.setContentAreaFilled(false);
        clear.setContentAreaFilled(false);

    }// end of design()

    private void setTriggers() {
        ActionListener actionTrigger = new ActionListener() {
            public void actionPerformed(ActionEvent anActionEvent) {
                if (anActionEvent.getSource() == okay) {
                    verifyID();
                } else if (anActionEvent.getSource() == clear) {
                    cleanUp();
                }
            }
        };// end of viewerTrigger() method

        okay.addActionListener(actionTrigger);
        clear.addActionListener(actionTrigger);
    }// end of setTriggers

    // checks whether the new ID is not yet used
    private boolean iDIsUnique() {
        prepareConnection();

        String verifyQuery = "SELECT * FROM requirementstrackerschema.student"
            + " WHERE studentID = ?";

        try {
            preparedStatement = connection
                .prepareStatement(verifyQuery);
            preparedStatement.setString(1, iD.getText());

            resultSet = preparedStatement.executeQuery();

            // if there is an existing one
            if (resultSet.next()) {
                JOptionPane.showMessageDialog(null,
                    "ID number already exists!");
                return false;
            } else { // if newID is unique
                return true;
            } // end of if-else
        } catch (Exception e) {
            e.printStackTrace();
        } // end of try-catch

        return false;
    }// end of iDIsUnique method

    private boolean iDIsNotNull() {
        if (iD.getText().isEmpty()) {
            JOptionPane.showMessageDialog(null,
                "Please enter an ID number.");
            return false;
        } else {
            return true;
        } // end of else
    } // end of iDIsNotNull method

    private boolean iDIsNumbers() {
        try {
            Integer.parseInt(iD.getText());
            return true;
        } catch (NumberFormatException nfe) {
            JOptionPane.showMessageDialog(null,
                "Please enter a valid ID number.");
            return false;
        } // end of try-catch
    } // end of iDIsNumbers method

    private boolean iDHasSevenChars() {
        if (iD.getText().length() == 7) {
            return true;
        } else {
            JOptionPane.showMessageDialog(null,
                "An ID number should be 7 characters long!");
            return false;
        } // end of if-else
    } // end of iDHasSevenChars method

    private void verifyID() {
        if (iDIsNotNull() && iDIsNumbers() && iDHasSevenChars()
            && iDIsUnique()) {
            verifyPin();
        } else {
        }
    } // end of verifyID method

    // a method that checks whether the pins match
    private void verifyPin() {
        String pin1 = pin.getText();
        String pin2 = confirmPin.getText();

        // if pins match
        if (pin1.equals(pin2)) {
            createAccount();
        } else { // if do not match
            JOptionPane.showMessageDialog(null, "Pins don't match.");
        } // end of if-else
    } // end of verifyPin method

    // a method that creates new account
    private void createAccount() {
        String createQuery = "INSERT INTO requirementstrackerschema.student"
            + " VALUES " + getEntries();

        try {
            DatabaseUtility.executeQuery(createQuery);

            JOptionPane.showMessageDialog(null,
                "Your account has been created!");

            cleanUp();

            // show profileAuthenticator
            ((CardLayout) (ProfileMenu.getCards().getLayout())).show(
                ProfileMenu.getCards(), "profileAuthenticator");

        } catch (Exception e) {
            e.printStackTrace();
        } // end of try-catch
    } // end of createAccount method

    private String getEntries() {
        String studentIDInput = iD.getText();
        String pinInput = pin.getText();

        return "('" + studentIDInput + "','" + pinInput + "','0')";
    } // end of getEntries method

    public void cleanUp() {
        iD.setText("");
        pin.setText("");
        confirmPin.setText("");
    } // end of cleanUp method
}// end of ProfileMaker